home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 July / macformat-026.iso / mac / Shareware City / Science / µSim 1.0 folder / Libs / CursorBalloon.c < prev    next >
Encoding:
Text File  |  1995-01-21  |  5.7 KB  |  208 lines  |  [TEXT/MMCC]

  1. /*
  2. Copyright © 1993,1994 by Fabrizio Oddone
  3. ••• ••• ••• ••• ••• ••• ••• ••• ••• •••
  4. This source code is distributed as freeware: you can copy, exchange, modify this
  5. code as you wish. You may include this code in any kind of application: freeware,
  6. shareware, or commercial, provided that full credits are given.
  7. You may not sell or distribute this code for profit.
  8. */
  9.  
  10. //#pragma load "MacDump"
  11.  
  12.  
  13. #include    "UtilsSys7.h"
  14. #include    "CursorBalloon.h"
  15.  
  16. static void myShowBalloon(RgnHandle theGlobalCoordsRgn,
  17.                             unsigned long theBalloon,
  18.                             short variant);
  19.  
  20. /* globals for the manager */
  21.  
  22. RgnHandle    mouseRgn, wideOpenRgn;
  23.  
  24. /*
  25. The window will "remember" an object; you pass the following characteristics:
  26. •    the region enclosing the object, in local coordinates;
  27. •    the procedure recalculating the object region (in local coordinates);
  28.     this will be called automatically whenever the window size changes;
  29.     if the object will never be resized, pass nil;
  30.     Here is the prototype for the recalcProc:
  31. void RecalcIO(WindowPtr w, RgnBalloonCursPtr theObj);
  32. •    the cursor (B&W) associated with this object;
  33.     if you want the standard arrow cursor, pass nil;
  34. •    the balloon that will appear when Balloon Help is on;
  35.     use this macro: toBalloon(ID_of_STR#_resource, index );
  36.     if you do not want a balloon, pass 0L;
  37. •    the variant of the balloon (see Inside Macintosh for the meaning of this)
  38.     if you do not want a balloon, pass 0;
  39. */
  40.  
  41. OSErr InstallRgnHandler(FabWindowPtr w, RgnHandle whichRgn, void (*recalcProc)(FabWindowPtr, RgnBalloonCursPtr),
  42.                         CursHandle cursor,
  43.                         unsigned long balloon, short ballnVariant, short iID)
  44. {
  45. RgnBalloonCurs    t;
  46. register OSErr err = appMemFullErr;
  47.  
  48. t.recalcRgnProc = recalcProc;
  49. t.zoneLocal = whichRgn;
  50. t.curs = cursor;
  51. t.myBalloon = balloon;
  52. t.balloonVariant = ballnVariant;
  53. t.itemID = iID;
  54. t.zoneGlobal = NewRgn();
  55. if (t.zoneGlobal) {
  56.     CopyRgn(whichRgn, t.zoneGlobal);
  57.     OffsetRgn(t.zoneGlobal, -(((WindowPtr)w)->portBits.bounds.left), -(((WindowPtr)w)->portBits.bounds.top));
  58.     
  59.     if ((err = PtrAndHand(&t, (Handle)Zones(w), sizeof(RgnBalloonCurs))) == noErr)
  60.         OneMoreObject(w);
  61.     }
  62. return err;
  63. }
  64.  
  65. /* Recalculate the mouse region; you pass:
  66. •    a WindowPtr (not necessarily a FabWindowPtr);
  67. •    the mouse position (in global coordinates);
  68. */
  69.  
  70. void RecalcMouseRegion(WindowPtr w, Point mouse)
  71. {
  72. register RgnBalloonCursPtr    curObj;
  73. register unsigned long    i;
  74.  
  75. if ((IsFabWindow(w)) && (NumObjects(w))) {
  76.     CopyRgn(wideOpenRgn, mouseRgn);
  77.     HLockHi((Handle)Zones(w));
  78.     for (i = 1, curObj = *Zones(w); i <= NumObjects(w); i++, curObj++) {
  79.         if (PtInRgn(mouse, curObj->zoneGlobal)) {
  80.             if (curObj->curs)
  81.                 SetCursor(*curObj->curs);
  82.             else
  83.                 SetCursor(&qd.arrow);
  84.             if (curObj->myBalloon)
  85.                 if (HMGetBalloons())
  86.                     myShowBalloon(curObj->zoneGlobal, curObj->myBalloon,
  87.                                     curObj->balloonVariant);
  88.             CopyRgn(curObj->zoneGlobal, mouseRgn);
  89.             break;
  90.             }
  91.         else
  92.             DiffRgn(mouseRgn, curObj->zoneGlobal, mouseRgn);
  93.         }
  94.     if (i > NumObjects(w))
  95.         SetCursor(&qd.arrow);
  96.     HUnlock((Handle)Zones(w));
  97.     }
  98. else {
  99.     CopyRgn(wideOpenRgn, mouseRgn);
  100.     SetCursor(&qd.arrow);
  101.     }
  102. }
  103.  
  104. /* Resizes the dynamic objects of the window by calling the recalcProc
  105. for every object */
  106.  
  107. void ResizeObjects(FabWindowPtr w)
  108. {
  109. register void (*theProc)(FabWindowPtr, RgnBalloonCursPtr);
  110. register RgnBalloonCursPtr    curObj;
  111. register unsigned long    i;
  112.  
  113. if (NumObjects(w)) {
  114.     HLockHi((Handle)Zones(w));
  115.     for (i = 1, curObj = *Zones(w); i <= NumObjects(w); i++, curObj++) {
  116.         theProc = curObj->recalcRgnProc;
  117.         if (theProc)
  118.             theProc(w, curObj);
  119.         }
  120.     HUnlock((Handle)Zones(w));
  121.     }
  122. }
  123.  
  124. /* Calculates the regions for the given FabWindow in global coordinates,
  125. so that they are ready for WaitNextEvent
  126. */
  127.  
  128. void RecalcGlobalCoords(FabWindowPtr w)
  129. {
  130. register RgnBalloonCursPtr    curObj;
  131. register unsigned long    i;
  132. Point    mypt = { 0, 0};
  133.  
  134. if (NumObjects(w)) {
  135.     HLockHi((Handle)Zones(w));
  136.     LocalToGlobal(&mypt);
  137.     for (i = 1, curObj = *Zones(w); i <= NumObjects(w); i++, curObj++) {
  138.         CopyRgn(curObj->zoneLocal, curObj->zoneGlobal);
  139. // -(((WindowPtr)w)->portBits.bounds.left)
  140. // -(((WindowPtr)w)->portBits.bounds.top)
  141.         OffsetRgn(curObj->zoneGlobal, mypt.h, mypt.v);
  142.         }
  143.     HUnlock((Handle)Zones(w));
  144.     }
  145. }
  146.  
  147. /* myShowBalloon: common routine for showing up balloons */
  148.  
  149. static void myShowBalloon(RgnHandle theGlobalCoordsRgn,
  150.                             unsigned long theBalloon, short variant)
  151. {
  152. HMMessageRecord    helpMsg;
  153. Point    myTip;
  154.  
  155. myTip.v = (*theGlobalCoordsRgn)->rgnBBox.top + 3;
  156. myTip.h = (*theGlobalCoordsRgn)->rgnBBox.right - 3;
  157. helpMsg.hmmHelpType = khmmStringRes;
  158. *(unsigned long *)&helpMsg.u.hmmStringRes.hmmResID = theBalloon;
  159. //helpMsg.u.hmmStringRes.hmmIndex = *(((short *)(&theBalloon)) +1);
  160. if (hmBalloonAborted == HMShowBalloon(&helpMsg, myTip, &(*theGlobalCoordsRgn)->rgnBBox,
  161.                                         nil, 0, variant, kHMRegularWindow))
  162.     ForceMouseMovedEvent();
  163. }
  164.  
  165. void DisposFabWindow(FabWindowPtr w)
  166. {
  167. register RgnBalloonCursHandle    tempH;
  168. register RgnBalloonCursPtr    spanPtr;
  169. register unsigned long    i;
  170.  
  171. tempH = Zones(w);
  172. HLock((Handle)tempH);
  173. spanPtr = *tempH;
  174.  
  175. for (i = 0; i < NumObjects(w); i++, spanPtr++) {
  176.     DisposeRgn(spanPtr->zoneLocal);
  177.     DisposeRgn(spanPtr->zoneGlobal);
  178. /* we do nothing with the CursHandles since they might be system cursors */
  179.     }
  180. DisposeHandle((Handle)tempH);
  181. // the caller knows whether CloseWindow or CloseDialog is to be called
  182. }
  183.  
  184. void ForceMouseMovedEvent(void)
  185. {
  186. SetRectRgn(mouseRgn, 32761, 32761, 32765, 32765);
  187. }
  188.  
  189. void InitFabWindow(FabWindowPtr w)
  190. {
  191. // not needed because we allocate the structure with NewPtrClear
  192. /*
  193. SetActivate(w, nil);
  194. SetUpdate(w, nil);
  195. SetDrag(w, nil);
  196. SetGrow(w, nil);
  197. SetZoom(w, nil);
  198. SetGoAway(w, nil);
  199. SetContent(w, nil);
  200. NumObjects(w) = 0;
  201. */
  202. Zones(w) = (RgnBalloonCursHandle)NewHandle(0);
  203. if (((WindowPeek)w)->windowKind != dialogKind)
  204.     ((WindowPeek)w)->windowKind = kFabWindowClass;
  205.  
  206. }
  207.  
  208.